package com.ztesoft.report.backstage;


import com.ztesoft.report.backstage.dao.ReportDataCreateDao;
import com.ztesoft.report.backstage.job.ReportDataCreateJob;
import com.ztesoft.report.backstage.job.ReportDataFileUploadJob;
import com.ztesoft.report.dao.ReportDataFileUploadDao;
import com.ztesoft.report.entity.ServiceInterface;
import com.ztesoft.report.exception.RException;
import com.ztesoft.report.service.ServiceInterfaceService;
import com.ztesoft.report.thread.GeneralThreadPool;
import com.ztesoft.report.thread.ThreadUtil;
import com.ztesoft.report.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.*;

@Slf4j
@Component
@PropertySource(value = "classpath:backStageJob.properties")
public class BackStageApplication implements ApplicationListener<ApplicationReadyEvent> {

    @Autowired
    ReportDataCreateDao reportDataCreateDao;

    @Autowired
    ReportDataFileUploadJob reportDataFileUploadJob;

    @Autowired
    ServiceInterfaceService serviceInterfaceService;

    @Autowired
    ReportDataFileUploadDao reportDataFileUploadDao;

    @Value("${com.ztesoft.handleCount}")
    Integer handleCount;

    @Value("${com.ztesoft.interval}")
    Integer interval;

    //线程休眠时间间隔
    Long sleepTime = 10L;

    private GeneralThreadPool pool;

    /**
     * 监听启动，程序启动时自动启动2个后台服务
     * @param applicationReadyEvent
     */
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {

        log.info("开始后台数据扫描.........");
        //检查数据库开关BACKSTAGE_FLAG,默认0关闭，1开启
        Integer backstageFlag = reportDataCreateDao.selectFlag();
        if (backstageFlag == 0) {
            log.info("检测到开关为关闭状态,后台服务不启动........");
            return;
        }
        //重置00D,00F状态,处理中--->待处理，在每一次程序启动时候执行一次（避免上次未处理完的情况）
        Integer statusDCount = reportDataCreateDao.selectStatus("00D");
        if (statusDCount > 0) {
            Map<String, Object> oodChange = new HashMap<>();
            oodChange.put("oldstatus", "00D");
            oodChange.put("newstatus", "00W");
            reportDataCreateDao.updateStatus(oodChange);
        }
        Integer statusFCount = reportDataCreateDao.selectStatus("00F");
        if (statusFCount > 0) {
            Map<String, Object> oofChange = new HashMap<>();
            oofChange.put("oldstatus", "00F");
            oofChange.put("newstatus", "00E");
            reportDataCreateDao.updateStatus(oofChange);
        }
        if (pool == null) {
            // 创建线程池
            pool = ThreadUtil.createThreadPool(handleCount,handleCount,1,50000);
        }
        while (true) {
            //扫描是否存在待处理的数据，如果不存在则直接让线程休眠
            Integer statusWCount = reportDataCreateDao.selectStatus("00W");
            Integer statusECount = reportDataCreateDao.selectStatus("00E");
            if (statusWCount == 0 && statusECount == 0) {
                log.info("本次处理结束！休眠" + interval + "秒");
                try {
                    Thread.sleep(interval * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                continue;
            }
            //获取状态为00W或者00E的首条记录，更改状态为处理中
            List<String> list = new ArrayList<>();
            list.add("00W");
            list.add("00E");
            ServiceInterface serviceInterface = reportDataCreateDao.selectOneService(list);
            if ("00W".equals(serviceInterface.getStatus())) {
                serviceInterface.setStatus("00D");
                serviceInterface.setUpdateTime(new Date());
                serviceInterfaceService.updateServiceInterface(serviceInterface);
            }
            if ("00E".equals(serviceInterface.getStatus())) {
                serviceInterface.setStatus("00F");
                serviceInterface.setUpdateTime(new Date());
                serviceInterfaceService.updateServiceInterface(serviceInterface);
            }
            try {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        //报表数据生成服务
                        if ("00D".equals(serviceInterface.getStatus())) {
                            ReportDataCreateJob reportDataCreateJob = SpringContextUtil.getBean(ReportDataCreateJob.class);
                            reportDataCreateJob.run(serviceInterface);
                        }
                        //报表生成文件上传服务
                        if ("00F".equals(serviceInterface.getStatus())) {
                            ReportDataFileUploadJob reportDataFileUploadJob = SpringContextUtil.getBean(ReportDataFileUploadJob.class);
                            reportDataFileUploadJob.run(serviceInterface);
                        }
                    }
                };
                pool.executeTask(runnable,sleepTime);
            } catch (Exception e) {
                serviceInterfaceService.updateById(serviceInterface);
                throw new RException(e.getMessage());
            }

        }
    }
}